package ctxSemanticsGen;

import java.net.URL;
import java.util.ArrayList;
import java.util.Properties;


import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.RuntimeConstants;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;

import pluginGenerator.PluginResourceLoader;

import ctxSemanticsGen.appDependent.ClassFetcher;
import ctxSemanticsGen.appDependent.VelocityInitializer;


/**
 * This class represents set of classes for which a conttextual semantics 
 * must be generated.
 * 
 * @author guido
 *
 */
public class CtxSemanticsGenerator {
	
	private String outputPath;
	private ArrayList<String> classesToProcess;
	private ArrayList<String> layersInSystem;
	private ClassFetcher cf;
	private VelocityInitializer rl;
	
	/**
	 * Create a COP semantics generator. The ClassFetcher is used to convert 
	 * class string into Class objects.
	 * 
	 * @param path
	 * @param classesToProcess
	 * @param layersInSystem
	 * @param cf
	 */
	public CtxSemanticsGenerator(String path, ArrayList<String> classesToProcess,
							                  ArrayList<String> layersInSystem,
							                  ClassFetcher cf, 
							                  VelocityInitializer rl){
		this.outputPath = path;
		this.classesToProcess = classesToProcess;
		this.layersInSystem = layersInSystem;
		this.cf = cf;
		this.rl = rl;
	}
	
	
	public void run() throws ClassNotFoundException{

		// Extract all the class structures
		ArrayList<ClassStructure> classStructures = new ArrayList<ClassStructure>();
		for(String s: classesToProcess){
			Class c = cf.fetchClass(s);						
			ClassStructure cs = new ClassStructure(c);
			classStructures.add(cs);
		}
		
		// All the layer classes
		ArrayList<Class> layers = new ArrayList<Class>();
		for (String ln: layersInSystem){
			//Class.forName(ln);
			Class layerClass = cf.fetchClass(ln);
			layers.add(layerClass);		
		}
		

		/* Ready for code generation */
		rl.initializeVelocity();

		// Generate all the aspects for each class
		for(ClassStructure cs: classStructures){
			ClassProcessor cp = new ClassProcessor(cs);
			cp.generateAspects(outputPath);
		}
		
		// Generate LayerWrappers except the Base layer
		for (Class layerClass: layers){
			WrapperGenerator wg = new WrapperGenerator(layerClass, classStructures);
			wg.generateWrapper(outputPath);
		}
		
		// Generate the BaseLayerWrapper
		BaseLayerWrapperGenerator blwg = new BaseLayerWrapperGenerator(classStructures);
		blwg.generateWrapper(outputPath);
		
		// Generate the LayerWrapper
		ParentWrapperGenerator pwg = new ParentWrapperGenerator(classStructures);
		pwg.generateWrapper(outputPath);
		
		// Generate the LayerWrapperManager
		LayerWrapperManagerGenerator lwmg = new LayerWrapperManagerGenerator(layers);
		lwmg.generateWrapper(outputPath);
		
	}
	
}

